package deployment

import (
	"context"
	"krm_pro/config"
	"net/http"

	"github.com/gin-gonic/gin"
	appsv1 "k8s.io/api/apps/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	typedv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
)

// deploy := appsv1.Deployment{
// 		TypeMeta: metav1.TypeMeta{
// 			APIVersion: "apps/v1",
// 			Kind:       "deployment",
// 		},
// 		ObjectMeta: metav1.ObjectMeta{
// 			Name:      info.Name,
// 			Namespace: info.Namespace,
// 			Labels:    info.Labels,
// 		},
// 		Spec: appsv1.DeploymentSpec{
// 			Replicas: &info.Replicas,
// 			Template: corev1.PodTemplateSpec{
// 				ObjectMeta: metav1.ObjectMeta{
// 					Labels: info.Labels,
// 				},
// 				Spec: corev1.PodSpec{
// 					Containers: []corev1.Container{
// 						{
// 							Name:  info.Name,
// 							Image: info.Image,
// 						},
// 					},
// 				},
// 			},
// 		},
// 	}

var clientsetDeployment = config.ClientSet.AppsV1().Deployments

type DeploymentType struct {
	InstanceInterface typedv1.AppsV1Interface
	deployTypeData    appsv1.Deployment
	Name              string `json:"name"`
	Namespace         string `json:"namespace"`
}

func DeploymentList(r *gin.Context) {
	d := DeploymentType{}
	if err := r.ShouldBindJSON(&d); err != nil {
		r.JSON(http.StatusOK, gin.H{
			"status":  401,
			"message": "type bond flase",
		})
		return
	}
	if d.Namespace == "" {
		r.JSON(http.StatusOK, gin.H{
			"status":  200,
			"message": "namespace not be empty ",
		})
		return
	}
	deploy := d.list()
	r.JSON(http.StatusOK, gin.H{
		"status": 200,
		"data":   deploy.Items,
	})
}

func DeploymentGet(r *gin.Context) {
	d := DeploymentType{}
	if err := r.ShouldBindJSON(&d); err != nil {
		r.JSON(http.StatusOK, gin.H{
			"status":  401,
			"message": "type bond flase",
		})
		return
	}
	if d.Namespace == "" || d.Name == "" {
		r.JSON(http.StatusOK, gin.H{
			"status":  200,
			"message": "namespace or name is not be empty ",
		})
		return
		// panic("namespace or name is not be empty")
	}
	r.JSON(http.StatusOK, gin.H{
		"status": 200,
		"data":   d.get(),
	})
}

func DeploymentCreate(r *gin.Context) {
	d := DeploymentType{}
	if err := r.ShouldBindYAML(&d); err != nil {
		r.JSON(http.StatusOK, gin.H{
			"status":  401,
			"message": "type bond flase",
		})
		return
	}

	// err := json.Unmarshal(deployment), )
	// if err != nil {
	// 	fmt.Println("转换失败")
	// }
	if _, err := clientsetDeployment(d.Namespace).Get(context.TODO(), d.Name, metav1.GetOptions{}); err != nil {
		if errors.IsNotFound(err) {
			d.create()
			r.JSON(http.StatusOK, gin.H{
				"status":  200,
				"message": "deployment create completed",
			})
			return
		}
		r.JSON(http.StatusOK, gin.H{
			"status":  200,
			"message": "deployment already exists",
		})
		return
	}
}

func DeploymentUpdate(r *gin.Context) {
	deployType := DeploymentType{}
	if err := r.ShouldBindJSON(&deployType); err != nil {
		r.JSON(http.StatusOK, gin.H{
			"status":  401,
			"message": "type bond flase",
		})
		return
	}
	deployType.update()
	r.JSON(http.StatusOK, gin.H{
		"status": 200,
		"data":   "deploy",
	})
}

func DeploymentDelete(r *gin.Context) {
	deployType := DeploymentType{}
	if err := r.ShouldBindJSON(&deployType); err != nil {
		r.JSON(http.StatusOK, gin.H{
			"status":  401,
			"message": "type bond flase",
		})
		return
	}
	if deployType.Namespace == "" || deployType.Name == "" {
		r.JSON(http.StatusOK, gin.H{
			"status":  200,
			"message": "namespace or name is not be empty ",
		})
		return
	}
	deployType.delete()
	r.JSON(http.StatusOK, gin.H{
		"status":  200,
		"message": "deployment delete completed",
	})
}

func (d *DeploymentType) list() *appsv1.DeploymentList {
	// clientset := config.ClientSet.AppsV1().Deployments
	deploy, err := clientsetDeployment(d.Namespace).List(context.TODO(), metav1.ListOptions{})
	if err != nil {
		panic(err.Error())
	}
	return deploy
}

func (d *DeploymentType) get() *appsv1.Deployment {
	deploy, err := clientsetDeployment(d.Namespace).Get(context.TODO(), d.Name, metav1.GetOptions{})
	if err != nil {
		panic(err.Error())
	}
	return deploy
}

func (d *DeploymentType) create() {
	_, err := clientsetDeployment(d.Namespace).Create(context.TODO(), &d.deployTypeData, metav1.CreateOptions{})
	if err != nil {
		panic(err.Error())
	}
}

func (d *DeploymentType) update() *appsv1.Deployment {
	deploy, err := clientsetDeployment(d.Namespace).Update(context.TODO(), &d.deployTypeData, metav1.UpdateOptions{})
	if err != nil {
		panic(err.Error())
	}
	return deploy
}

func (d *DeploymentType) delete() {
	err := clientsetDeployment(d.Namespace).Delete(context.TODO(), d.Name, metav1.DeleteOptions{})
	if err != nil {
		panic(err.Error())
	}
}
